var TwinklGame = TwinklGame || {};
(function (TwinklGame, manifest) {
//CHANGE FONT SIZE ------------------------------------------------------------------------------------------------------------------------
var theWidth,
minWidth = 1184,
screenIsSmall = true,
isFullscreen = false,
fontArr = [
{element:'.title-text', size_sm:'13vw', size_lg: '170px'},
{element:'.font-button', size_sm:'4vw', size_lg: '58px'},
{element:'.sub-heading', size_sm:'3vw', size_lg: '48px'},
{element:'.jodal-title', size_sm:'5vw', size_lg: '70px'},
//{element:'.jodal-text', size_sm:'2.6vw', size_lg: '30px'},
{element:'.text-button', size_sm:'3vw', size_lg: '40px'},
//ADD IN ANY TEXT TO MAKE SURE IT RESPONDS CORRECTLY
];
function resizeScreen(){
theWidth = $('body').width();
var smallDisplay = true;
theWidth >= minWidth && (smallDisplay = false);
isFullscreen && (smallDisplay = true);
if (smallDisplay != screenIsSmall) {
screenIsSmall = !screenIsSmall;
$.each(fontArr, function(key, value){
var newSize = smallDisplay ? value.size_sm : value.size_lg;
$(value.element).css('font-size', newSize);
});
}
//ADD IN ANYTHING ELSE THAT NEEDS TO RESPOND DIFFERENTLY(CIRCLE BUTTONS ETC)
}
//AUDIO SAMPLES----------------------------------------------------------------------------------------------------------------------------------------------
var buttonClickAudio = new Howl({src: [manifest.buttonClick.src]}),
correctAnswerSoundAudio = new Howl({src: [manifest.correctAnswerSound.src]}),
wrongAnswerAudio = new Howl({src: [manifest.wrongAnswerSound.src]}),
swooshAudio = new Howl({src: [manifest.swoosh.src]}),
clickAudio = new Howl({src: [manifest.click.src]});
//------------------------------------------------------------------------------------------------------------------------------------------------------------
TwinklGame.setup = function (config) {
resizeScreen();
$(window).resize(resizeScreen);
$(window).resize(textResize);
//SEARCH FOR SUPERSCRIPT
config.cards.forEach(function(e,elem){
config.cards[elem].topText = detectFraction(config.cards[elem].topText);
config.cards[elem].bottomText = detectFraction(config.cards[elem].bottomText)
});
config.title = detectFraction(config.title);
// VARIABLES-----------------------------------------------------------------------------------------------------------------------------------------------
var wholeDocument = $("#matching-template-container"),
allPages = $(".pages"),
titlePage = $("#titlePage"),
instructionsPage = $("#instructionsPage"),
mainPage = $("#mainPage"),
soundToggle = $(".sound-toggle"),
navBar = $(".go-nav-panel"),
fullScreen = $("#fullscreen-button"),
titleText = $("#title"),
subHeading = $("#subContainer"),
allInstructions = $(".allInstructions"),
closeButton = $("#close-button"),
letsGo = $("#lets-go-button"),
playButton = $("#playButton"),
instructionsPanel = $("#instructionsPanel");
//SETUP BACKGROUND IMAGE & ALL TEXT------------------------------------------------------------------------------------------------------------------------
wholeDocument.addClass('interactive-theme-' + config.theme_colour);
$("#matching-template-container").addClass(config.branding+"-branding");
if(config.branding =="twinkl"){
$(".main-twinkl-logo").show();
}
else if(config.branding=="beyond"){
$("#matching-template-container").css('font-family', '"roboto" !important');
$(".main-twinkl-logo").hide();
$(".beyond-twinkl-logo").show();
}
if(config.background_music) {
var backgroundMusic = new Howl({src: [config.background_music.assetUrl], autoplay: true, volume: 0.7, loop: true});
}
wholeDocument.css({ "background-image": "url(" + config.background_image_url.assetUrl + ")" });
$("#mainPage").css({ "background-image": "url(" + config.desk_background_image_url.assetUrl + ")" });
titleText.html(config.title); textResize();
subHeading.html(config.sub_title);
$("#how-to-play").html(config.intro_title);
allInstructions.html(config.intro_text);
$(".instant-feedback-title").html(config.success_title);
$("#congrats-screen-text").html(config.success_text);
$("#next-question-button").html(config.next_button_text);
$("#isItCorrect").html(config.success_title);
$(".fit-me-button").html(config.lets_go_text);
$("#playButton").html(config.play_button_text);
$("#play-again").html(config.play_again_button_text);
closeButton.hide();
hidePages();
function hidePages(){
allPages.hide();
titlePage.show();
}
//GET AND STORE AUDIO FILES
//ADD ANY ELEMENTS IN HERE YOU WANT TO REMOVE WIDOWS FROM---------------------------------------------------------------------------------------------------
titleText.widowFix();
//INSERT ANYTHING THAT NEEDS TO FIT TO CONTAINER------------------------------------------------------------------------------------------------------------
function textResize(){
testFontSize(titleText,180);
testFontSize($(".fit-me-button"),50);
TwinklGame.Utils.fitText($('#congrats-screen-text'),55)
}
//START GAME------------------------------------------------------------------------------------------------------------------------------------------------
letsGo.click(function(){
swooshAudio.play();
instructionsPage.show();
instructionsPanel.css({'top':'100%'}).animate({'top':'15%'},500,"easeOutBack");
titlePage.hide();
TwinklGame.Utils.fitText($(".allInstructions"),40);
});
//PLAY BUTTON-----------------------------------------------------------------------------------------------------------------------------------------------
playButton.click(function(){
buttonClickAudio.play();
instructionsPage.hide();
mainPage.show();
invertNav();
textResize();
setTimeout(function(){
shake($(".movable-matching-card"));
},100)
fitText();
});
//INSERT GAME CODE HERE **************************************************************************************************************************************
//DECLARE ALL USED VARIABLES
var newArray,usable,used,gotImage,gotText,totalPoints,cardPos,inPlace,totalQuestionScore,allQuestionsTotalScore;
config.cards.forEach(function(e,p){
e.id = p;
});
resetWholeGame();
function resetWholeGame(){
newArray = $.extend(true, [], config.cards);
TwinklGame.Utils.shuffleArray(newArray);
usable = [];
used = [];
gotImage =false;
gotText = false;
totalPoints = 0;
inPlace = 0;
totalQuestionScore = 10;
allQuestionsTotalScore= 0;
resetCards();
$(".round-result-screen").hide();
}
function resetCards(){
$(".pulsate").removeClass("pulsate")
//REMOVE CARDS AND MAKE CARDS AGAIN
buildMatchingCards();
inPlace = 0;
usable = [];
totalQuestionScore = 10;
if(newArray.length>=4){
if(containsSwearWords(newArray.slice(0, 4))===true){
TwinklGame.Utils.shuffleArray(newArray)
}
usable = newArray.splice(0, 4)
} else{
var sparesNeeded = (4 - newArray.length);
usable = newArray.splice(0, newArray.length).concat(used.splice(0,sparesNeeded));
}
//RESET THE LAYOUT TO STANDARD
$(".drop-area-top-image").removeClass("drop-area-top-image");
$(".drop-area-top-text").removeClass("drop-area-top-text");
//ADD TOP CARDS
cardPos= "top"; addImageAndText("#matching-card-drop-");
TwinklGame.Utils.shuffleArray(usable); //SHUFFLE ARRAY
//ADD BOTTOM CARDS
cardPos= "bottom"; addImageAndText("#movable-matching-card-");
used = used.concat(usable);
addDragAndDrop();
setTimeout(function(){
fitText();
}, 100);
}
function buildMatchingCards(){
$(".drop-area-bottom, .matching-cards").empty();
for(var i =1; i<5;i++) {
var newCode = '
'
$(".matching-cards").append(newCode)
}
}
function shake(element){
element.parent().addClass("bounce");
setTimeout(removeShake,1000);
function removeShake(){
element.parent().removeClass("bounce")
}
}
//FILTER OUT ANY POTENTIAL SWEAR WORDS--- --------------------------------------------------------------
function containsSwearWords(usable) {
const swearWords = [
"fuck", "tits", "feck", "knob", "clit", "shag", "jizz", "jism", "gism",
"mong", "damn", "hell", "shit", "dick", "twat", "slut", "cunt", "slag",
"piss", "crap", "cock", "butt", "fart", "wank", "poop", "boob", "dyke",
"crud", "darn", "turd", "heck", "drat", "porn", "pimp", "meth", "rape",
"twit", "arse", "twot", "coon", "frig", "kike", "spaz", "spas", "bint",
"bich", "koon", "paki", "pleb", "drug", "anus", "hoes", "gimp", "homo",
"wang", "muff", "turd", "flid", "kunt", "nazi", "smeg", "tard", "phuc",
"fucc", "phuk", "dago", "poof"
];
// Function to check if two strings are permutations of each other
function arePermutations(str1, str2) {
const normalize = str => str.toLowerCase().split('').sort().join('');
return normalize(str1) === normalize(str2);
}
// Combine all topText elements
const combinedTopText = usable.map(obj => obj.topText).join('').toLowerCase();
// Check each swear word
for (const swear of swearWords) {
if (arePermutations(combinedTopText, swear)) {
return true; // Found a match
}
}
return false; // No matches found
}
//TEST IMAGE AND TEXT DATA AND ATTACH TO CARD
function addImageAndText(e){
//ADD TOP CARDS
for(var i =0; i<4;i++){
gotImage =false; gotText = false;
var s = $(e+(i+1));
if(usable[i].crossMatch?.length>0){
s.attr('data-cross',usable[i].crossMatch);
}
s.attr('data-id',usable[i].id);
//IF HAS IMAGE
if(usable[i][cardPos+"Image"] && usable[i][cardPos+"Image"].assetUrl.length>0){
s.find($(".image-area")).css('background-image', 'url(' + usable[i][cardPos+"Image"].assetUrl + ')');
gotImage=true;
}
if(usable[i][cardPos+"Text"] && usable[i][cardPos+"Text"].length>0){
s.find($(".text-area")).html(usable[i][cardPos+"Text"]);
gotText=true
}
//CHECK SEE IF RUNNING THROUGH TOP CARDS OR BOTTOM
if(cardPos =="top"){s=s.find($(".drop-area-top"))}
//IF HAS JUST IMAGE OR JUST TEXT CHANGE CLASS
//IF HAS JUST IMAGE OR JUST TEXT CHANGE CLASS
if(gotImage ===true && gotText ===false){ s.addClass("drop-area-top-image"); }
else if(gotImage ===false && gotText ===true){s.addClass("drop-area-top-text")}
}
}
$("#next-question-button").on("click",function(){
if(newArray.length<1){
$(".pages").hide();
$("#well-done").show();
$("#well-done").css({'top':'100%'}).animate({'top':'15%'},500,"easeOutBack");
swooshAudio.play();
TwinklGame.Utils.fitText($('#congrats-screen-text'),55)
} else{
buttonClickAudio.play();
resetCards();
$(".round-result-screen").hide();
}
});
$("#play-again").on("click",function(){
buttonClickAudio.play();
$(".pages").hide();
$("#mainPage").show();
resetWholeGame();
});
function addDragAndDrop() {
$(".movable-matching-card").draggable({
start:function(event,ui){
$(this).css({"transform":"rotate(4deg)","transition":"transform 0.2s"})
},
stop:function(event,ui){
$(this).css({"transform":"rotate(0deg)"})
},
revert: true,
});
$(".drop-area-bottom").droppable({
drop: function (ev, ui) {
var getIdea = $(this).parent().attr("data-id");
$(".movable-matching-card").removeClass("being-dragged-too")
if (getIdea === $(ui.draggable).attr("data-id") || ($(this).parent().attr("data-cross") && $(ui.draggable).attr("data-cross")) && $(this).parent().attr("data-cross") === $(ui.draggable).attr("data-cross")) {
$(ui.draggable).detach().css({top: 0, left: 0}).appendTo(this);
$(ui.draggable).draggable('disable');
inPlace++;
$(this).parent().addClass("pulsate");
clickAudio.play();
$(ui.draggable).css({"transform":"rotate(0deg)", "transition":"none!important"})
//$(this).css({"transform":"rotate(0deg)", "transition":"none!important"})
} else {
wrongAnswerAudio.play()
if(totalQuestionScore>=2){
totalQuestionScore--
}
}
if (inPlace === 4) {
setTimeout(function(){
$(".round-result-screen").show();
$("#instant-feedback-popup").css({'top': '100%'}).animate({'top': '15%'}, 500, "easeOutBack");
workOutRoundScore();
swooshAudio.play();
},100)
}
}
});
function workOutRoundScore(){
allQuestionsTotalScore = (allQuestionsTotalScore+totalQuestionScore);
//HIDE STAR 2 and 3 AND SHOW DEPENDING ON QUESTIONS CORRECT
$("#star-solid-2, #star-solid-3").css({"color":"#fcaf17"});
if(totalQuestionScore < 10){$("#star-solid-3").css({"color":"lightgray"})}
if(totalQuestionScore < 7){$("#star-solid-2").css({"color":"lightgray"})}
//if(totalQuestionScore === 10){$("#star-solid-3").show();}
//if(totalQuestionScore >= 7){$("#star-solid-2").show();}
}
$(".movable-matching-card").on("mousedown",function(e){
var num = $(this).attr("data-id");
var audio = search(num,usable);
//MAKE CLICKED COME TO FRONT
$(".movable-matching-card").parent().css({"z-index":"1"});
$(this).parent().css({"z-index":"3"});
if(audio){
var newAudio1 = new Howl({src: audio});
newAudio1.play();
}else{
buttonClickAudio.play();
}
})
}
//CHECK
function search(nameKey, myArray){
for (var i=0; i < myArray.length; i++) {
if (myArray[i].id == nameKey && myArray[i].bottomAudio) {
if(myArray[i].bottomAudio.assetUrl.length>0){
return myArray[i].bottomAudio.assetUrl;
}else {
return false;
}
}
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------
function detectFraction(superChar) {
//console.log(superChar,"YEs")
// var split = superChar.split(/(?=\[)|(?<=\])/); //SPLIT BY []
var split = splitBetween(superChar,"[","]");
if(split.length>1){
//FOR EACH SPLIT IN THE TEXT (EACH SUM)
split.forEach(function (e, index) {
if (e.includes("[")) {
var without = e.substring(1);
without = without.substring(0, without.length - 1); //TAKE OFF END CHARACTERS
// var array = without.split(/(?' +array.join("") + '';
}else{
split[index] = '' +split[index] + '';
}
});
return '' +split.join("") + '
';
}else{
return split.join("");
}
}
function splitBetween(array,char1,char2){
var newArray =[];
var marker;
for(var i=0;i<=array.length;i++){
if(array[i]===char1 ){
newArray.push(array.slice(marker,i));
marker =i;
}
else if(array[i]===char2 ){
newArray.push(array.slice(marker,(i+1)));
marker =(i+1);
}
else if(i===(array.length)){
newArray.push(array.slice(marker,i));
}
}
return newArray;
}
function splitAll(array,char1,char2,char3,char4){
var newArray =[];
var marker=0;
for(var i=0;i<=array.length;i++){
if(array[i]===char1 ){
newArray.push(array.slice(marker,i)); //(
newArray.push(array.slice(i,i+1)); //(
marker =i+1;
}
else if(array[i]===char2 ){
newArray.push(array.slice(marker,i)); //(
newArray.push(array.slice(i,i+1)); //(
marker =i+1;
}
else if(array[i]===char3 ){
newArray.push(array.slice(marker,i)); //(
newArray.push(array.slice(i,i+1)); //(
marker =i+1;
}
else if(array[i]===char4 ){
newArray.push(array.slice(marker,i)); //(
newArray.push(array.slice(i,i+1)); //(
marker =i+1;
}
else if(i===(array.length)){
newArray.push(array.slice(marker,i));
}
}
return newArray;
}
function changeArray(array){
array.forEach(function(e,index){
if(e=="^"){
array[index]="";
array = searchStopForward("^",array,index);
}else if(e=="/"){
array[index] = "";
array = searchStopForward("/",array,index);
array = searchStopBack("/",array,index);
}else{
array[index]= detectAlgebra(array[index],array[index+1]);
}
array=array
});
//REMOVE BRACKETS
array.forEach(function(e,index){if(e=="(" || e==")"){array.splice(index, 1);}});
return array;
}
function searchStopBack(input,array,index){
var points = 0,temp;
for(var i=index;i>=0;i--){
if(array[i]==")"){
points++
}else if(array[i]=="("){
if(points==0){
array.splice(i, 0, generateCode(input,"backward",array[i]));
temp=array;
break
}else{
points--;
}
}
if(i===0){ //IF REACHES END
array.splice(i, 0, generateCode(input,"backward",array[i]));
temp=array;
break;
}
}
return temp;
}
function searchStopForward(input,array,index){
var points = 0,temp;
for(var i=index;i<=array.length;i++){
if(array[i]=="("){
points++
}else if(array[i]==")"){
if(points==0){
array.splice(i, 0, generateCode(input,"forward",array[i]));
temp =array;
break;
}else{
points--;
}
}
if(i==array.length){ //IF REACHES END
array.push(generateCode(input,"forward",array[i]));
temp=array;
break;
}
}
return temp;
}
function generateCode(input, direction,text){
if(input =="/"){
if(direction=="forward"){
return "
"
}else{
return "";
}
}else if (input =="^"){
if(direction=="forward"){
return '';
}else{
return '
'+ text;
}
}
}
//CHANGE ALGEBRAEIC LETTERE
function detectAlgebra(string,next){
// var arr = string.split(/(?=\<)|(?<=\>)/); //SPLIT BUT KEEP IN
var regex = /(.*?<\/div>)|(.*?<\/span>) /;
var arr= string.split(regex).filter(Boolean);
arr.forEach(function(e,i){
if(e.includes("<")){ //CHECK NOT IN A SPAN OR SUP
//0
}else{
var margin="";
if(next!=undefined && next.includes("^")){
margin = "margin-right:0;"
}else{
margin = "margin-right:0.2em ;"
}
arr[i] = arr[i].replace(/[A-Za-z]/g,function(x){return "" +x+""});
}
});
return arr.join("");
}
//NAVIGATION FUNCTIONS ******************************************************************************************************************************************
//CLOSE BUTTON
function fitText(){
for(var i = 1;i<=4;i++){
var me = $("#matching-card-drop-" + i).find($(".text-area"))
testFontSize(me, 60)
}
for(var i = 1;i<=4;i++){
var me2 = $("#movable-matching-card-" + i).find($(".text-area"))
testFontSize(me2, 60)
}
}
closeButton.click(function(){
buttonClickAudio.play();
hidePages();
invertNav();
textResize();
resetWholeGame();
});
//INVERT THE NAVIGATION COLOURS AND TOGGLE CLOSE
function invertNav(){
fullScreen.toggleClass("inverted");
soundToggle.toggleClass("inverted");
navBar.toggleClass("theme-background-dark");
closeButton.toggle();
}
//FULLSCREEN TOGGLE ---------------------------------------------------------------
fullScreen.click(function () {
buttonClickAudio.play();
fitText();
if(fullScreen.hasClass("expand-screen"))
{fullScreen
.removeClass("expand-screen")
.addClass("reduce-screen");
TwinklGame.Utils.makeFullScreen(document.getElementById('matching-template-container'));
}
else{
fullScreen
.removeClass("reduce-screen")
.addClass("expand-screen");
TwinklGame.Utils.leaveFullScreen();
}
});
$(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', function () {
isFullscreen = !isFullscreen;
resizeScreen();
textResize();
fitText();
});
//SOUND TOGGLE -----------------------------------------------------------------------
soundToggle.click(function () {
buttonClickAudio.play();
if(soundToggle.hasClass("sound-off"))
{soundToggle
.removeClass("sound-off")
.addClass("sound-on");
Howler.mute(true);
}else{
soundToggle
.removeClass("sound-on")
.addClass("sound-off");
Howler.mute(false);
}
});
//CHECK IF TEXT OVERFLOWS----------------------------------------------------------------
function testFontSize(e, s) {
e.css( "font-size", s + ("px"));
var size = e.css('font-size'); //GETS FONT SIZE
size = parseInt(size, 10); //REMOVE PX
//WHILE TEXT OVERFLOWS ELEMENT REDUCE TEXT SIZE
for(;e.get(0).offsetHeight